﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CreateCheck.cs" company="SmartPlan">
//   SmartPlan 2011
// </copyright>
// <summary>
//   The create check.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace DbDiff.Common.Scripting
{
    using System;
    using DataAccess;

    /// <summary>
    /// The create check.
    /// </summary>
    internal class CreateCheck : CreateBase
    {
        /// <summary>
        /// The current script.
        /// </summary>
        private readonly CreateTable currentScript = new CreateTable();

        /// <summary>
        /// The table check row
        /// </summary>
        private DbObjectsDs.CheckRow ir;

        /// <summary>
        /// Initializes a new instance of the <see cref="CreateCheck"/> class.
        /// </summary>
        /// <param name="schema">
        /// The schema.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="databaseDataSets">
        /// The dt objects.
        /// </param>
        /// <param name="scrOption">
        /// The scr option.
        /// </param>
        public CreateCheck(string schema, string tableName, DatabaseDataSets databaseDataSets, SqlScriptingOption scrOption) : base(schema, tableName, string.Empty, databaseDataSets, scrOption)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CreateCheck"/> class.
        /// </summary>
        /// <param name="schema">
        /// The schema.
        /// </param>
        /// <param name="tableName">
        /// The table name.
        /// </param>
        /// <param name="columnName">
        /// The column name.
        /// </param>
        /// <param name="databaseDataSets">
        /// The dt objects.
        /// </param>
        /// <param name="scrOption">
        /// The scr option.
        /// </param>
        public CreateCheck(string schema, string tableName, string columnName, DatabaseDataSets databaseDataSets, SqlScriptingOption scrOption) : base(schema, tableName, columnName, databaseDataSets, scrOption)
        {
        }

        /// <summary>
        /// Gets sqlScript.
        /// </summary>
        public CreateTable SqlScript
        {
            get
            {
                return this.currentScript;
            }
        }

        /// <summary>
        /// The make string.
        /// </summary>
        public void MakeString()
        {
            base.ToString();
        }

        /// <summary>
        /// The to string.
        /// </summary>
        /// <returns>
        /// return Exception
        /// </returns>
        /// <exception cref="Exception">
        /// </exception>
        public override string ToString()
        {
            throw new Exception("You can't use ToString()");
        }

        /// <summary>
        /// The set rows.
        /// </summary>
        protected override void SetRows()
        {
            this.DataRowViews = this.DatabaseDiffData.GetCheckConstraints(this.Schema, this.TableName, this.Name);
        }

        /// <summary>
        /// The set current row.
        /// </summary>
        protected override void SetCurrentRow()
        {
            if (this.DataRowViews.Length > 0)
            {
                this.ir = (DatabaseDataSets.CheckRow)this.DataRowViews[this.CurrentRow].Row;
            }
        }

        /// <summary>
        /// The row script.
        /// </summary>
        protected override void RowScript()
        {
            if (this.ir == null)
            {
                return;
            }

            string sqlDefinition = this.ir.Definition;

            // if we used with nocheck or disabled we must have to add a name!!!!
            // because we have to make alter script for check constraint
            // not trusted eseten először létre kell hozni a a consrtaint-et
            // igy:ALTER TABLE [dbo].[jobs]  WITH CHECK ADD CHECK  (([max_lvl] <= 250))
            // ez csak azt jelenti, hogy a constraint létrehotásakor nem volt ellenőrizve a 
            // tartalom, hanem csak a később bekerült adatokra
            // MSSQL BUG:cr.CnsIsNotTrusted not checked 
            if (!this.ir.CnsIsDisabled)
            {
                if (!this.ir.NoName)
                {
                    this.currentScript.afterField.AddElement(string.Format("{0} {1}", cmdConstraint, QuoteName(this.ir.Name)), true, true);
                }

                this.currentScript.afterField.AddElement(string.Format("{0} {1} {2}", cmdCheck, this.ir.CnsNotForReplication ? cmdNotForReplication : string.Empty, sqlDefinition), this.ir.NoName, true);
                this.currentScript.afterField.AddRowWithComma();
            }
            else
            {
                // NOCHECK,DISABLE
                this.currentScript.afterCreateForAlter.AddCommandTerminator(AddCheckConstraintNoCheck(this.Schema, this.Name, this.ir, sqlDefinition));
            }
        }

        /// <summary>
        /// Alter table [schema][tablename] nocheck check CONSTSRAINT [constraint name]
        /// alter table [dbo].[jobs] nocheck constraint [CK__jobs__min_lvl__5535A963]
        /// </summary>
        /// <param name="schema">
        /// The schema name
        /// </param>
        /// <param name="name">
        /// The name of the table
        /// </param>
        /// <param name="cr">
        /// The check row
        /// </param>
        /// <param name="text">
        /// The current text.
        /// </param>
        /// <returns>
        /// The add check constraint no check.
        /// </returns>
        private static string AddCheckConstraintNoCheck(string schema, string name, DatabaseDataSets.CheckRow cr, string text)
        {
            var msc = new MiscCommand();
            string s = msc.AlterTable(schema, name);

            // NAME with check
            // alter table [dbo].[jobs] nocheck constraint [CK__jobs__min_lvl__5535A963]
            // s+=

            // NONAME with nocheck
            // ALTER TABLE [dbo].[jobs]  WITH CHECK ADD CHECK  (([max_lvl] <= 250))
            if (cr.NoName)
            {
                s += string.Format(" {0} {1}", cmdCheckWithNoCheckAddCheck, text);
            }
            else
            {
                // ALTER TABLE [dbo].[AllColumnType2]  WITH NOCHECK ADD  CONSTRAINT [CK_AllColumnType2] CHECK  (([columnwithcheckconstraint] <> ''))
                s += string.Format(" {0} {1} {2} {3}", cmdAddWithNoCheckAddConstraint, cr.Name, cmdCheck, text);
            }

            return s;
        }
    }
}